home *** CD-ROM | disk | FTP | other *** search
/ The PC-SIG Library 10 / The PC-Sig Library - Shareware for the IBM PC and Compatibles (PC-SIG)(Tenth Edition Disks 1-2804)(1991).iso / PC_SIGCD / 22 / 4 / DISK2247.ZIP / CBASE101.ZIP / ROLODECK.ZIP / CVTSS.C < prev    next >
Text File  |  1990-06-21  |  6KB  |  236 lines

  1. /*    Copyright (c) 1989 Citadel    */
  2. /*       All Rights Reserved        */
  3.  
  4. /* #ident    "@(#)cvtss.c    1.4 - 90/06/22" */
  5.  
  6. /*#define huge        /* include this definition if NOT using MS-DOS */
  7.  
  8. #include <blkio.h>    /* ansi compatibility macros */
  9.  
  10. /* ansi headers */
  11. #include <ctype.h>
  12. #include <errno.h>
  13. /*#include <stddef.h>*/
  14. #include <stdio.h>
  15. /*#include <stdlib.h>*/
  16. /*#include <string.h>*/
  17.  
  18. /* local headers */
  19. #include "basstr.h"
  20.  
  21. /* macros */
  22. #define max(a,b)    ((a) > (b) ? (a) : (b))
  23. #define min(a,b)    ((a) < (b) ? (a) : (b))
  24.  
  25. /* macro to preserve characters within single and double quotes */
  26. #define QUOTES {                            \
  27.     char c = NUL;                            \
  28.     if (quotes && (*ps == '\'' || *ps == '\"')) {            \
  29.         c = *ps;                        \
  30.         *pt++ = *ps++;                        \
  31.         while (pt < ttend) {                    \
  32.             *pt++ = *ps;                    \
  33.             if (*ps == c || *ps == NUL) break;        \
  34.         }                            \
  35.         continue;                        \
  36.     }                                \
  37. }
  38.  
  39. /*man---------------------------------------------------------------------------
  40. NAME
  41.      cvtss - convert string
  42.  
  43. SYNOPSIS
  44.      int cvtss(t, s, m, n)
  45.      char *t;
  46.      const char *s;
  47.      int m;
  48.      int n;
  49.  
  50. DESCRIPTION
  51.      The cvtss function takes the source string pointed to by s,
  52.      performs the conversions indicated by m, and places the result in
  53.      the target string pointed to by t.  n is the size of the target
  54.      string.  At most n characters are placed in t.
  55.  
  56.      Values for m are constructed by bitwise OR-ing flags from the
  57.      following list.  These macros are defined in basstr.h.
  58.  
  59.      CVT_TP               Trim the parity bit.
  60.      CVT_XSP              Discard spaces and tabs.
  61.      CVT_XCTL             Discard control characters.
  62.      CVT_XLEADSP          Discard leading spaces and tabs.
  63.      CVT_1SP              Reduce spaces and tabs to one space.
  64.      CVT_UPPER            Convert lowercase to uppercase.
  65.      CVT_BTOP             Convert [ to ( and ] to ).
  66.      CVT_XTRAILSP         Discard trailing spaces and tabs.
  67.      CVT_QUOTES           Do not alter characters inside single or
  68.                           double quotes except for parity bit
  69.                           trimming.
  70.  
  71.      cvtss will fail if one or more of the following is true:
  72.  
  73.      [EINVAL]       t or s is the NULL pointer.
  74.      [EINVAL]       n is less than 0.
  75.  
  76. DIAGNOSTICS
  77.      Upon successful completion, a value of 0 is returned.  Otherwise,
  78.      a value of -1 is returned, and errno set to indicate the error.
  79.  
  80. NOTES
  81.      cvtss is adapted directly from the BASIC function CVT$$.
  82.  
  83. ------------------------------------------------------------------------------*/
  84. int cvtss(t, s, m, n)
  85. char *t;
  86. const char *s;
  87. int m;
  88. int n;
  89. {
  90.     char *ts = NULL;    /* temporary source string */
  91.     char *tt = NULL;    /* temporary target string */
  92.     char huge *ttend = NULL;    /* first char past end of tt */
  93.     int ns = 0;        /* size of ts */
  94.     int quotes = 0;        /* preserve quoted characters flag */
  95.     int bit = 0;        /* bit number */
  96.     char huge *ps = NULL;    /* pointer into ts */
  97.     char huge *pt = NULL;    /* pointer into tt */
  98.     int flag = 0;        /* gp flag */
  99.  
  100.     /* validate arguments */
  101.     if (t == NULL || s == NULL || n < 0) {
  102.         errno = EINVAL;
  103.         return -1;
  104.     }
  105.     if (n < 1) {
  106.         errno = 0;
  107.         return 0;
  108.     }
  109.  
  110.     /* find size for ts */
  111.     ns = max(strlen(s) + 1, n);
  112.  
  113.     /* create temporary strings */
  114.     ts = (char *)calloc((size_t)ns, sizeof(*ts));
  115.     if (ts == NULL) {
  116.         errno = ENOMEM;
  117.         return -1;
  118.     }
  119.     tt = (char *)calloc((size_t)n, sizeof(*tt));
  120.     if (tt == NULL) {
  121.         free(ts);
  122.         errno = ENOMEM;
  123.         return -1;
  124.     }
  125.     ttend = tt + n;
  126.  
  127.     /* initialize ts with s */
  128.     strcpy(ts, s);
  129.  
  130.     /* perform conversions */
  131.     quotes = m & CVT_QUOTES;    /* set preserve quoted chars flag */
  132.     for (bit = 0; m != 0; ++bit, m >>= 1) {
  133.         if (!(m & 1)) {
  134.             continue;
  135.         }
  136.         switch (bit) {
  137.         case 0:    /* trim the parity bit */
  138.             for (ps = ts, pt = tt; pt < ttend; ++ps) {
  139.                 QUOTES;
  140.                 *pt++ = *ps & 0x7F;
  141.                 if (*ps == NUL) break;
  142.             }
  143.             break;    /* case 0: */
  144.         case 1:    /* discard all spaces and tabs */
  145.             for (ps = ts, pt = tt; pt < ttend; ++ps) {
  146.                 QUOTES;
  147.                 if (!(*ps == ' ' || *ps == '\t')) {
  148.                     *pt++ = *ps;
  149.                 }
  150.                 if (*ps == NUL) break;
  151.             }
  152.             break;    /* case 1: */
  153.         case 2:    /* discard all control characters */
  154.             for (ps = ts, pt = tt; pt < ttend; ++ps) {
  155.                 QUOTES;
  156.                 if (*ps == '\t') {
  157.                     *pt++ = ' ';
  158.                 } else if (!iscntrl(*ps) || *ps == NUL) {
  159.                     *pt++ = *ps;
  160.                 }
  161.                 if (*ps == NUL) break;
  162.             }
  163.             break;    /* case 2: */
  164.         case 3:    /* discard leading spaces and tabs */
  165.             for (ps = ts; *ps == ' ' || *ps == '\t'; ++ps) {
  166.             }
  167.             strncpy(tt, ps, n);
  168.             break;    /* case 3: */
  169.         case 4:    /* reduce spaces and tabs to one space */
  170.             flag = 0;
  171.             for (ps = ts, pt = tt; pt < ttend; ++ps) {
  172.                 QUOTES;
  173.                 if (flag) {
  174.                     if (*ps != ' ' && *ps != '\t') {
  175.                         *pt++ = *ps;
  176.                         flag = 0;
  177.                     }
  178.                 } else {
  179.                     if (*ps == ' ' || *ps == '\t') {
  180.                         *pt++ = ' ';
  181.                         flag = 1;
  182.                     } else {
  183.                         *pt++ = *ps;
  184.                     }
  185.                 }
  186.                 if (*ps == NUL) break;
  187.             }
  188.             break;    /* case 4: */
  189.         case 5:    /* convert lowercase to uppercase */
  190.             for (ps = ts, pt = tt; pt < ttend; ++ps) {
  191.                 QUOTES;
  192.                 *pt++ = toupper(*ps);
  193.                 if (*ps == NUL) break;
  194.             }
  195.             break;    /* case 5: */
  196.         case 6:    /* convert [ to ( and ] to ) */
  197.             for (ps = ts, pt = tt; pt < ttend; ++ps) {
  198.                 QUOTES;
  199.                 if (*ps == '[') *pt = '(';
  200.                 else if (*ps == ']') *pt = ')';
  201.                 else *pt = *ps;
  202.                 ++pt;
  203.                 if (*ps == NUL) break;
  204.             }
  205.             break;    /* case 6: */
  206.         case 7:    /* discard trailing spaces and tabs */
  207.             for (ps = ts + strlen(ts) - 1;
  208.                 ps >= ts && (*ps == ' ' || *ps == '\t'); ps--) {
  209.             }
  210.             strncpy(tt, ts, n);
  211.             tt[min(n - 1, ps + 1 - ts)] = NUL;
  212.             break;    /* case 7: */
  213.         case 8:    /* do not alter characters inside quotes */
  214.             continue;
  215.             break;    /* case 8: */
  216.         default:
  217.             free(tt);
  218.             free(ts);
  219.             errno = EINVAL;
  220.             return -1;
  221.             break;
  222.         }
  223.         strncpy(ts, tt, ns);
  224.     }
  225.  
  226.     /* load target string */
  227.     strncpy(t, ts, n);
  228.  
  229.     /* free temporary strings */
  230.     free(tt);
  231.     free(ts);
  232.  
  233.     errno = 0;
  234.     return 0;
  235. }
  236.